import java.io.*;
import java.util.*;
import java.util.Map.Entry;
import org.xml.sax.*;
import org.xml.sax.helpers.*;

public class Baseline extends DefaultHandler {
  private TreeMap<String, TreeMap<String, Integer>> wordSenseMap_;
  private String inputFile_;
  private String outFile_;
  private String testFile_;
  private Writer out;

  public Baseline(String inputFile, String testFile, String outFile) {
    inputFile_ = inputFile;
    outFile_ = outFile;
    testFile_ = testFile;
    wordSenseMap_ = new TreeMap<String, TreeMap<String, Integer>>();
  }

  public String getMostFreqSense(String word) {
    String sense = null;
    TreeMap<String, Integer> map = wordSenseMap_.get(word);
    if (map == null) {
      return null;
    }
    int maxCount = 0;
    for (Entry<String, Integer> entry : map.entrySet()) {
      if (entry.getValue() > maxCount) {
        maxCount = entry.getValue();
        sense = entry.getKey();
      }
    }
    return sense;
  }

  public void train() {
    String line;
    try {
      FileReader reader = new FileReader(inputFile_);
      BufferedReader br = new BufferedReader(reader);
      while ((line = br.readLine()) != null) {
        String[] fields = line.split(" ");
        String word = fields[0];
        String sense = fields[2];
        // TODO : Handling more than one sense
        TreeMap<String, Integer> map = wordSenseMap_.get(word);
        if (map == null) {
          map = new TreeMap<String, Integer>();
        }
        int count = 0;
        if (map.containsKey(sense)) {
          count = map.get(sense);
        }
        map.put(sense, ++count);
        wordSenseMap_.put(word, map);
      }
    } catch (Exception e) {
      e.printStackTrace();
    }
    // System.out.println(wordSenseMap);
  }

  public void test() {
    String tmpFile = "tmp.xml";
    try {
      FileWriter writer = new FileWriter(tmpFile);
      FileReader reader = new FileReader(testFile_);
      out = new FileWriter(outFile_);
      XMLReader xmlr = XMLReaderFactory.createXMLReader();
      xmlr.setContentHandler(this);
      xmlr.setErrorHandler(this);

      BufferedReader br = new BufferedReader(reader);
      WSD.formatXMLfile(br, writer);
      reader.close();
      reader = new FileReader(tmpFile);

      // Parse the intermediate XML file.
      xmlr.parse(new InputSource(reader));
      out.close();
    } catch (IOException ex) {
      throw new RuntimeException(ex);
    } catch (SAXParseException spe) {
      StringBuffer sb = new StringBuffer(spe.toString());
      sb.append("\n  Line number: " + spe.getLineNumber());
      sb.append("\nColumn number: " + spe.getColumnNumber());
      sb.append("\n Public ID: " + spe.getPublicId());
      sb.append("\n System ID: " + spe.getSystemId() + "\n");
      System.out.println(sb.toString());
    } catch (SAXException se) {
      System.out.println("loadDOM threw " + se);
      se.printStackTrace(System.out);
    }
  }

  /*
   * Grabs the opening SGML tag.
   */
  private String currWord = null;

  @Override
  public void startElement(String uri, String name, String qName,
      Attributes atts) {
    String instance = null;
    if (qName.equals("lexelt")) {
      currWord = atts.getValue("item");
    } else if (qName.equals("instance")) {
      instance = atts.getValue("id");
      String sense = getMostFreqSense(currWord);
      String str = currWord + " " + instance + " " + sense;
      // System.out.println(str);
      try {
        out.write(str + "\n");
      } catch (IOException e) {
        e.printStackTrace();
      }
    }
  }

  /*
   * Grabs the closing tag.
   */
  @Override
  public void endElement(String uri, String name, String qName) {
  }

  /*
   * This prints out all the text between the tags we care about to a file.
   */
  @Override
  public void characters(char ch[], int start, int length) {
  }

  @Override
  public void endDocument() throws SAXException {
  }

  public static void main(String[] args) {

    String inputFile = "data/EnglishLS/EnglishLS.train.key";
    String outFile = "data/scorer/Baseline.output.keys";
    String testFile = "data/EnglishLS/EnglishLS.test";

    for (int i = 0; i < args.length; i = i + 2) {
      if (args[i].equalsIgnoreCase("-i"))
        inputFile = args[i + 1];
      if (args[i].equalsIgnoreCase("-o"))
        outFile = args[i + 1];
      if (args[i].equalsIgnoreCase("-t"))
        testFile = args[i + 1];
    }

    Baseline bsl = new Baseline(inputFile, testFile, outFile);
    bsl.train();
    bsl.test();
  } // end of main

} // end of class Baseline
